﻿#include "localTcpClient.h"
#include "logger.h"
localTcpClient::localTcpClient()
{
    m_host = "";
    m_port = 5000;
    myClient = new hv::TcpClient;
    is_connect = false;
}

localTcpClient::~localTcpClient()
{
    if(myClient)
    {
        SAFE_DELETE(myClient);
        myClient = nullptr;
    }
}

bool localTcpClient::init(const int port, const std::string host)
{
    m_host = host;
    m_port = port;

    myClient->onConnection = [this](const hv::SocketChannelPtr& channel)
    {
        std::string peeraddr = channel->peeraddr();
        if (channel->isConnected()) {

            if(false == is_connect){
                LOG(INFO) <<"connected to " << peeraddr <<", connfd=" <<channel->fd() << std::endl;
                is_connect = true;
            }

        }else {
            if(true == is_connect){
                LOG(INFO) <<"disconnected to " << peeraddr <<", connfd=" <<channel->fd() << std::endl;
                is_connect = false;
            }
        }
    };

    myClient->onMessage = [this](const hv::SocketChannelPtr& channel, hv::Buffer* buf) {
        //printf("\n<--- %s\n\n", (char*)buf->data());
        //        memset(buf->data(), 0, buf->size());
        if(client_cb){
            client_cb((char*)buf->data(), buf->size());
        }
    };

    myClient->onWriteComplete = [](const hv::SocketChannelPtr& channel, hv::Buffer* buf) {
        //printf("\n---> %s\n\n", (char*)buf->data());
    };
    return true;
}

bool localTcpClient::connect()
{
    if(myClient == nullptr)
        return false;

    connfd = myClient->createsocket(m_port, m_host.c_str());
    if (connfd < 0)
    {
        return false;
    }

    reconn_setting_init(&m_reconn);

    m_reconn.min_delay = 500;
    m_reconn.max_delay = 1000;
    m_reconn.delay_policy = 2;

    myClient->setReconnect(&m_reconn);

    myClient->start();

    return true;
}

void localTcpClient::disconnect()
{
    if(myClient)
    {
        if(myClient->isConnected())
            myClient->closesocket();
    }
}

bool localTcpClient::isConnected()
{
    return is_connect;
}

void localTcpClient::sendMsg(std::string msg)
{
    sendData((char*)msg.c_str(), msg.size());
}

void localTcpClient::sendData(char *data, int data_len)
{
    if(myClient)
    {
        if(is_connect){
            myClient->send(data, data_len);
        }else{
            LOG(INFO)<<"m_host =" <<m_host<<" m_port ="<< m_port <<"myClient not connected" << std::endl;
        }
    }
}

localTcpClientSync::localTcpClientSync()
{
    client_cb =std::bind(&localTcpClientSync::sync_recv_data, this, std::placeholders::_1, std::placeholders::_2);
}

int localTcpClientSync::sync_recv_data(char *buf, size_t sz)
{
    if( sz<0 || sz > (sizeof(mData)/sizeof(mData[0]))){
        LOG(ERROR)<<"sz =" <<sz<< " out of range err!" << std::endl;
        return -1;
    }
    memcpy(mData,buf,sz);
    mDataLen = sz;
    evtVar.notify();
    return 0;
}

int localTcpClientSync::sync_send_data(char *buf, size_t sz,int nms)
{
    evtVar.m_flag = false;
    sendData(buf,sz);
    if(false ==  evtVar.m_flag){
        int nRet = evtVar.wait(nms);
        if(nRet == -1){
            LOG(ERROR)<< "can not recv reply \n";
            return -1;
        }
    }
    return 0;
}
